package com.develop.data.loan.manager;

import com.develop.data.loan.manager.api.LoanRepaymentManager;
import com.develop.data.loan.manager.change.amount.L0001B0001LoanInstallmentInterestBudget;
import com.develop.data.loan.manager.change.amount.L0001B0001LoanInstallmentInterestOverdueBudget;
import com.develop.data.loan.manager.change.amount.L0001B0001LoanInstallmentInterestPenaltyBudget;
import com.develop.data.loan.model.LoanContract;
import com.develop.data.loan.model.LoanInstallment;
import lombok.extern.slf4j.Slf4j;
import org.javatuples.Pair;

import javax.money.MonetaryAmount;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
public class L0001B0001LoanRepaymentManager implements LoanRepaymentManager {


    @Override
    public LoanInstallment previewInstallmently(LoanInstallment installment, LocalDateTime point) {

        LoanContract contract = installment.getLoanContract();

        MonetaryAmount interestAccrual = new L0001B0001LoanInstallmentInterestBudget().preview(installment, point);
        MonetaryAmount interestOverdue = new L0001B0001LoanInstallmentInterestOverdueBudget().preview(installment, point);
        MonetaryAmount interestPenalty = new L0001B0001LoanInstallmentInterestPenaltyBudget().preview(installment, point);
        MonetaryAmount principleDueAccrual = new L0001B0001LoanInstallmentInterestPenaltyBudget().preview(installment, point);

        installment.setInstallmentInterestAccrual(interestAccrual);
        installment.setInstallmentInterestOverdue(interestOverdue);
        installment.setInstallmentInterestPenalty(interestPenalty);

        return installment;
    }

    @Override
    public MonetaryAmount previewAmountInstallmently(LoanInstallment installment, LocalDateTime point) {

        LoanInstallment previewed = previewInstallmently(installment, point);

        MonetaryAmount interestAccrual = previewed.getInstallmentInterestAccrual();
        MonetaryAmount interestOverdue = previewed.getInstallmentInterestOverdue();
        MonetaryAmount interestPenalty = previewed.getInstallmentInterestPenalty();

        MonetaryAmount interestPreview = interestAccrual.add(interestOverdue).add(interestPenalty);

        return interestPreview;

    }

    @Override
    public List<LoanInstallment> preview(LoanContract contract, LocalDateTime point) {
        contract.getLoanInstallments().forEach(installment -> {
            previewInstallmently(installment, point);
        });
        return contract.getLoanInstallments();
    }

    @Override
    public MonetaryAmount previewAmount(LoanContract contract, LocalDateTime point) {

        return contract.getLoanInstallments()
                .stream()
                .map(installment -> previewAmountInstallmently(installment, point)).reduce(MonetaryAmount::add)
                .get();
    }

    @Override
    public MonetaryAmount execute(LoanContract contract, LocalDateTime point, MonetaryAmount amount, List<Pair<Integer, String>> order) {
        //历史期次，当前期次还款

        //未来期次还款


        return null;
    }
}
